<template>
    <div id="dev-assistant">
        <el-tabs v-model="activeName" type="card" class="tabs" @tab-change="onTabChange">
            <el-tab-pane label="添加数据源" name="add-data-source">
                <div class="add-data-source data-source">
                    <div class="data-source-list ">
                        <el-tree :data="dataSource" :props="dataSourceProps" />
                    </div>
                    <div class="add-datasource-form">
                        <el-table v-if="addDataSourceHeight > 0" ref="tableRef" :data="addDataSourceForm"
                            style="width: 100%;" :height="addDataSourceHeight">
                            <el-table-column label="数据源">
                                <template #default="scope">
                                    <el-select v-model="scope.row.datasource" filterable default-first-option allow-create
                                        placeholder="选择数据源" size="small" clearable>
                                        <el-option v-for="item in dataSourceList()" :key="item" :label="item"
                                            :value="item" />
                                    </el-select>
                                </template>
                            </el-table-column>
                            <el-table-column label="数据库">
                                <template #default="scope">
                                    <el-select v-model="scope.row.database" filterable default-first-option allow-create
                                        placeholder="选择数据库" size="small" clearable>
                                        <el-option v-for="item in databaseList(scope.row.datasource)" :label="item"
                                            :value="item" />
                                    </el-select>
                                </template>
                            </el-table-column>
                            <el-table-column label="数据表">
                                <template #default="scope">
                                    <el-select v-model="scope.row.table" filterable default-first-option allow-create
                                        placeholder="选择数据表" size="small" clearable>
                                        <el-option v-for="item in dataTableList(scope.row.datasource, scope.row.database)"
                                            :key="item" :label="item" :value="item" />
                                    </el-select>
                                </template>
                            </el-table-column>
                            <el-table-column label="字段名">
                                <template #default="scope">
                                    <el-input v-model="scope.row.name" placeholder="请输入字段名" size="small"></el-input>
                                </template>
                            </el-table-column>
                            <el-table-column label="sql类型">
                                <template #default="scope">
                                    <el-select v-model="scope.row.sqlType" filterable placeholder="选择SQL类型" size="small"
                                        clearable>
                                        <el-option v-for="item in sqlTypeList" :key="item" :label="item" :value="item" />
                                    </el-select>
                                </template>
                            </el-table-column>
                            <el-table-column label="Java类">
                                <template #default="scope">
                                    <el-select v-model="scope.row.javaType" filterable placeholder="选择Java类" size="small"
                                        clearable>
                                        <el-option v-for="item in javaTypeList" :key="item" :label="item" :value="item" />
                                    </el-select>
                                </template>
                            </el-table-column>
                            <!-- <el-table-column label="Java类型">
                                <template #default="scope">
                                    <el-select v-model="scope.row.javaShortType" filterable placeholder="选择Java类型" size="small" clearable>
                                        <el-option v-for="item in javaShortTypeList"
                                            :key="item" :label="item" :value="item" />
                                    </el-select>
                                </template>
                            </el-table-column> -->
                            <el-table-column label="注释">
                                <template #default="scope">
                                    <el-input v-model="scope.row.comment" placeholder="请输入注释" size="small"></el-input>
                                </template>
                            </el-table-column>
                            <el-table-column label="操作">
                                <template #default="scope">
                                    <el-button size="small" type="danger" @click="deleteRow(scope.row)">删除</el-button>
                                </template>
                            </el-table-column>
                        </el-table>
                        <div class="form-btn">
                            <el-button type="primary" plain @click="addRoww">添加一行</el-button>
                            <el-button @click="importFromResultSet">从结果集中导入</el-button>
                            <el-button>从SQL中导入</el-button>
                            <el-button>从连接中导入</el-button>
                            <el-button type="primary" @click="releaseImport">发布</el-button>
                        </div>
                    </div>
                </div>
            </el-tab-pane>
            <el-tab-pane label="数据源" name="data-source">
                <div class="data-source data-source-preview">
                    <div class="data-source-list">
                        <el-tree :data="dataSource" :props="dataSourceProps" show-checkbox @check="onCheck" />
                    </div>
                    <div class="preview">
                        <!-- <div class="datasource-preview"></div> -->
                        <!-- <div class="database-preview"></div> -->
                        <div class="column-preview">
                            <el-table v-if="dataSourceHeight > 0" ref="tableRef" :data="columnData" style="width: 100%;"
                                :height="dataSourceHeight">
                                <el-table-column type="selection" width="55" />
                                <el-table-column label="数据源" prop="datasource" />
                                <el-table-column label="数据库" prop="database" />
                                <el-table-column label="数据表" prop="table" />
                                <el-table-column label="字段名" prop="name" />
                                <el-table-column label="sql类型" prop="sqlType" />
                                <el-table-column label="Java类" prop="javaType" />
                                <!-- <el-table-column label="Java类型" prop="javaShortType" /> -->
                                <el-table-column label="列注释" prop="comment" />
                            </el-table>
                        </div>
                    </div>
                </div>
            </el-tab-pane>
            <el-tab-pane label="代码模板" name="code-template">Config</el-tab-pane>
            <el-tab-pane label="代码生成" name="code-generate">Role</el-tab-pane>
        </el-tabs>

        <el-dialog v-model="importFromResultSetDialogVisible" title="从结果集导入">
            <el-form :model="importFromResultSetForm" ref="importFromResultSetForm" :rules="importFromResultSetFormRules">
                <el-form-item label="查询SQL">
                    <el-link @click="copySelectSql">
                        复制
                    </el-link>
                </el-form-item>
                <el-form-item label="数据源" prop="datasource">
                    <el-select v-model="importFromResultSetForm.datasource" filterable default-first-option allow-create
                        placeholder="选择数据源" clearable>
                        <el-option v-for="item in dataSourceList()" :key="item" :label="item" :value="item" />
                    </el-select>
                </el-form-item>
                <el-form-item label="数据库" prop="database">
                    <el-select v-model="importFromResultSetForm.database" filterable default-first-option allow-create
                        placeholder="选择数据库" clearable>
                        <el-option v-for="item in databaseList(importFromResultSetForm.datasource)" :key="item"
                            :label="item" :value="item" />
                    </el-select>
                </el-form-item>
                <el-form-item label="结果集" class="resultSetFormItem" prop="resultSet">
                    <!-- <el-input v-model="importFromResultSetForm.resultSet" :rows="1" clearable type="textarea" placeholder="粘贴结果集" resize="none"/> -->
                    <el-button @click="importResultSetFromClipBoard">从剪切板导入</el-button>
                    <el-link v-if="importFromResultSetForm.resultSet" style="margin-left: 10px;">已导入{{importFromResultSetForm.resultSet.length}}个字段</el-link>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="onImportFromResult">确定导入</el-button>
                </el-form-item>
            </el-form>
        </el-dialog>
    </div>
</template>
<script>
import copy from '@/utils/copy.js'
export default {
    data() {
        let dataSource = []
        //i是数据源
        for (let i = 1, l = 4; i < l; i++) {
            let database = []
            //j是数据库
            for (let j = i % 2, n = 4; j < n; j++) {
                let tables = []
                //k是数据表
                for (let k = i * j * 10, m = i * j * 10 + 3; k < m; k++) {
                    let columns = []
                    //b是字段
                    for (let b = k * 10, p = k * 10 + 3; b < p; b++) {
                        columns.push({
                            name: `字段${i}-${j}-${k}-${b}`,
                            sqlType: 'bigint',
                            javaType: 'java.lang.Long',
                            javaShortType: 'Long',
                            comment: '字段注释'+b*k,
                            table: '表' + k,
                            database: '数据库' + j,
                            datasource: '数据源' + i,
                            table_comment:'表注释'+i*j*k*b
                        })
                    }
                    tables.push({
                        name: '表' + k,
                        columns: columns,
                        database: '数据库' + j,
                        datasource: '数据源' + i
                    })
                }
                database.push({
                    name: '数据库' + j,
                    children: tables,
                    datasource: '数据源' + i
                })
            }
            dataSource.push({
                name: '数据源' + i,
                children: database
            })
        }
        return {
            activeName: "data-source",
            dataSource: dataSource,
            dataSourceProps: {
                label: 'name',
                children: 'children'
            },
            columnData: null,
            dataSourceHeight: 0,
            addDataSourceHeight: 0,
            addDataSourceForm: [],
            databaseCached: [],
            tableCached: [],
            sqlTypeList: ['int', 'bigint', 'varchar', 'date', 'datetime'],
            javaTypeList: ['java.lang.Integer', 'java.util.Date'],
            importFromResultSetDialogVisible: false,
            importFromResultSetForm: {},
            importFromResultSetFormRules: {
                datasource: [{ required: true, message: '请选择数据源' }],
                database: [{ required: true, message: '请选择数据库' }],
                resultSet: [{ required: true, message: '请导入结果集' }],
            }
        }
    },
    methods: {
        addRoww() {
            this.addDataSourceForm.push({})
        },
        onCheck(_, { checkedNodes }) {
            let checkedData = []
            //把选择的所有字段加到集合
            checkedNodes.forEach(data => {
                if (data.columns) {
                    checkedData.push(...data.columns)
                }
            })
            console.log("选择", checkedData)
            this.columnData = checkedData
        },
        deleteRow(row) {
            let ind = this.addDataSourceForm.indexOf(row)
            if (ind > -1) {
                this.addDataSourceForm.splice(ind, 1)
            } else {
                console.log("ind==-1")
            }

        },
        onTabChange(e) {
            //刷新高度
            this.$nextTick(this.reComputContentHeight)
        },
        reComputContentHeight() {
            //重新计算高度
            this.dataSourceHeight = this.$el.querySelector('.data-source-preview').offsetHeight
            let formBtnHeight = this.$el.querySelector('.form-btn').offsetHeight
            this.addDataSourceHeight = this.$el.querySelector('.add-data-source').offsetHeight - formBtnHeight
            console.log("dataSourceHeight", this.dataSourceHeight)
            console.log("addDataSourceHeight", this.addDataSourceHeight)
        },
        importFromResultSet() {
            this.importFromResultSetDialogVisible = true
        },
        copySelectSql() {
            copy(`SELECT
    t.TABLE_NAME AS table_name,
		t.TABLE_COMMENT AS table_comment,
    c.COLUMN_NAME AS column_name,
    c.DATA_TYPE AS column_type,
    c.COLUMN_COMMENT AS column_comment
FROM
    information_schema.tables AS t
JOIN
    information_schema.columns AS c
ON
    t.TABLE_NAME = c.TABLE_NAME and t.TABLE_SCHEMA = c.TABLE_SCHEMA
WHERE
    t.TABLE_SCHEMA = DATABASE();`)
            this.$message.success("已复制SQL语句")
        },
        dataSourceList() {
            let arr = []
            //提取所有数据源名称
            this.dataSource.forEach(ds => {
                arr.push(ds.name)
            })
            return arr
        },
        databaseList(datasourceName) {
            let null_datasourceName = "%^$#@B"
            //null值处理
            if (!datasourceName) {
                datasourceName = null_datasourceName
            }
            //从缓存读取以提升性能
            if (this.databaseCached[datasourceName]) {
                return this.databaseCached[datasourceName]
            }
            //筛选数据源
            let datasource
            if (datasourceName != null_datasourceName) {
                datasource = this.dataSource.filter(ds => ds.name == datasourceName)
            } else {
                datasource = this.dataSource
            }
            //从数据源中获取所有数据库，添加到结果集
            let set = new Set()
            datasource.forEach(ds => {
                ds.children.forEach(db => {
                    set.add(db.name)
                })
            })
            //去重，添加缓存
            let arr = Array.from(set)
            this.databaseCached[datasourceName] = arr
            return arr
        },
        dataTableList(datasourceName, databaseName) {
            let null_datasourceName = "%^$#@B"
            let null_databaseName = "#$%@SDF";
            //null值处理
            if (!datasourceName) {
                datasourceName = null_datasourceName
            }
            if (!databaseName) {
                databaseName = null_databaseName
            }
            //从缓存查询内容，以提升性能
            if (this.tableCached[datasourceName] && this.tableCached[datasourceName][databaseName]) {
                return this.tableCached[datasourceName][databaseName]
            }
            //过滤数据源
            let datasource
            if (datasourceName != null_datasourceName) {
                datasource = this.dataSource.filter(ds => ds.name == datasourceName)
            } else {
                datasource = this.dataSource
            }
            //从数据源中过滤数据库
            let database = []
            if (databaseName != null_databaseName) {
                datasource.forEach(ds => {
                    ds.children.forEach(db => {
                        if (db.name == databaseName) {
                            database.push(db)
                        }
                    })
                })
            } else {
                datasource.forEach(ds => {
                    database.push(...ds.children)
                })
            }
            //将所有库的表添加到set中去重
            let set = new Set()
            database.forEach(db => {
                db.children.forEach(tb => {
                    set.add(tb.name)
                })
            })
            //设置缓存
            let arr = Array.from(set)
            if (this.tableCached[datasourceName]) {
                this.tableCached[datasourceName][databaseName] = arr
            } else {
                this.tableCached[datasourceName] = []
                this.tableCached[datasourceName][databaseName] = arr
            }

            return arr
        },
        importResultSetFromClipBoard() {
            navigator.clipboard.readText()
                .then(text => {
                    let rows=text.split(/\r?\n|\r/)
                    let arr=[]
                    rows.forEach(row=>{
                        let data=row.split("\t")
                        arr.push({
                            table:data[0],
                            table_comment:data[1],
                            column_name:data[2],
                            column_type:data[3],
                            column_comment:data[4]
                        })
                    })
                    this.importFromResultSetForm.resultSet = arr
                    console.log(arr)
                })
                .catch(err => {
                    console.error('无法读取剪切板内容: ', err);
                });
        },
        onImportFromResult() {
            let form = this.$refs['importFromResultSetForm']
            form.validate((valid, fields) => {
                if (valid) {
                    let datasource=this.importFromResultSetForm.datasource
                    let database=this.importFromResultSetForm.database
                    let arr=[]
                    this.importFromResultSetForm.resultSet.forEach(row=>{
                        arr.push({
                            datasource,
                            database,
                            table:row.table,
                            name:row.column_name,
                            sqlType:row.column_type,
                            comment:row.column_comment
                        })
                    })
                    this.addDataSourceForm.push(...arr)
                    this.$nextTick(()=>{
                        this.$message.success("提交成功")
                    })
                } else {
                    console.log('error submit!', fields)
                }
            })
        },
        releaseImport(){
            console.log(this.addDataSourceForm)
        }
    },
    mounted() {
        this.reComputContentHeight()
    }
}
</script>
<style lang="scss">
#dev-assistant {
    width: 100%;
    height: 100%;

    .el-tree-node__expand-icon.is-leaf {
        color: transparent;
    }

    .tabs {
        height: 100%;
        width: 100%;
        display: flex;
        flex-direction: column;

        .el-tabs__content {
            flex: 1;

            >div {
                width: 100%;
                height: 100%;
            }
        }
    }

    .add-data-source {
        .add-datasource-form {
            flex: 1;
        }

        .form-btn {
            padding: 10px 0;
        }
    }

    .data-source {
        height: 100%;
        display: flex;

        .data-source-list {
            width: 200px;
            box-shadow: 1px 0px 10px #ccc;
            margin-right: 10px;
        }

        .preview {
            flex: 1;
        }
    }
}
</style>